<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="utf-8" />
  <meta name="description" content="记录学习生活的点点滴滴" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <title>
    C语言面试题4 |  Mysterious Blog
  </title>
  <meta name="generator" content="hexo-theme-ayer">
  <link rel="shortcut icon" href="/favicon.ico" />
<link rel="stylesheet" href="/dist/main.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/css/remixicon.min.css">
<link rel="stylesheet" href="/css/custom.css">
<script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>
<link rel="alternate" href="/atom.xml" title="Mysterious Blog" type="application/atom+xml">
</head>
</html>
<body>
  <div id="app">
    <main class="content on">
      <section class="outer">
  <article
  id="post-C语言面试题4"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    <header class="article-header">
<h1 class="article-title sea-center" style="border-left:0" itemprop="name">
  C语言面试题4
</h1>
    </header>
    <div class="article-meta">
      <a href="/2021/03/09/C%E8%AF%AD%E8%A8%80%E9%9D%A2%E8%AF%95%E9%A2%984/" class="article-date">
  <time datetime="2021-03-09T15:39:43.000Z" itemprop="datePublished">2021-03-09</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E5%AD%A6%E4%B9%A0/">学习</a>
  </div>
<div class="word_count">
    <span class="post-time">
        <span class="post-meta-item-icon">
            <i class="ri-quill-pen-line"></i>
            <span class="post-meta-item-text"> Word count:</span>
            <span class="post-count">5k</span>
        </span>
    </span>
    <span class="post-time">
        &nbsp; | &nbsp;
        <span class="post-meta-item-icon">
            <i class="ri-book-open-line"></i>
            <span class="post-meta-item-text"> Reading time≈</span>
            <span class="post-count">20 min</span>
        </span>
    </span>
</div>
    </div>
    <div class="article-entry" itemprop="articleBody">
  <p>1 预处理<br>问题1：什么是预编译？何时需要预编译？</p>
<a id="more"></a>
<p>答：<br>预编译又称预处理，是整个编译过程最先做的工作，即程序执行前的一些预处理工作。主要处理#开头的指令。如拷贝#include包含的文件代码、替换#define定义的宏、条件编译#if等。.<br>何时需要预编译：<br>1、总是使用不经常改动的大型代码体。<br>2、程序由多个模块组成，所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下，可以将所有包含文件预编译为一个预编译头。<br>问题2：写一个“标准”宏，这个宏输入两个参数并返回较小的一个<br>答:#define MIN(x, y) ((x)&lt;(y)?(x):(y)) //结尾没有;<br>问题3：#与##的作用？<br>答：#是把宏参数转化为字符串的运算符，##是把两个宏参数连接的运算符。<br>例如：<br>#define STR(arg) #arg      则宏STR(hello)展开时为”hello”<br>#define NAME(y) name_y    则宏NAME(1)展开时仍为name_y<br>#define NAME(y) name_##y   则宏NAME(1)展开为name_1<br>#define DECLARE(name, type) typename##_##type##_type，<br>则宏DECLARE(val, int)展开为int val_int_type<br>问题4：如何避免头文件被重复包含？<br>答：<br>例如，为避免头文件my_head.h被重复包含，可在其中使用条件编译：<br>#ifndef _MY_HEAD_H<br>#define _MY_HEAD_H   /<em>空宏</em>/<br>/<em>其他语句</em>/<br>#endif<br>2 关键字<br>问题1：static关键字的作用？<br>答：<br>Static的用途主要有两个，一是用于修饰存储类型使之成为静态存储类型，二是用于修饰链接属性使之成为内部链接属性。<br>1静态存储类型：<br>在函数内定义的静态局部变量，该变量存在内存的静态区，所以即使该函数运行结束，静态变量的值不会被销毁，函数下次运行时能仍用到这个值。<br>在函数外定义的静态变量——静态全局变量，该变量的作用域只能在定义该变量的文件中，不能被其他文件通过extern引用。<br>2 内部链接属性<br>    静态函数只能在声明它的源文件中使用。<br>问题2：const关键字的作用？<br>答：<br>1声明常变量，使得指定的变量不能被修改。<br>const int a = 5;/<em>a的值一直为5，不能被改变</em>/<br>const int b; b = 10;/<em>b的值被赋值为10后，不能被改变</em>/<br>const int <em>ptr; /*ptr为指向整型常量的指针，ptr的值可以修改，但不能修改其所指向的值</em>/<br>int <em>const ptr;/*ptr为指向整型的常量指针，ptr的值不能修改，但可以修改其所指向的值</em>/<br>const int <em>const ptr;/*ptr为指向整型常量的常量指针，ptr及其指向的值都不能修改</em>/<br>2修饰函数形参，使得形参在函数内不能被修改，表示输入参数。<br>如int fun(const int a);或int fun(const char <em>str);<br>3修饰函数返回值，使得函数的返回值不能被修改。<br>const char <em>getstr(void);使用：const *str= getstr();<br>const int getint(void);  使用：const int a =getint();<br>问题3：volatile关键字的作用？<br>答：<br>volatile指定的关键字可能被系统、硬件、进程/线程改变，强制编译器每次从内存中取得该变量的值，而不是从被优化后的寄存器中读取。例子:硬件时钟;多线程中被多个任务共享的变量等。<br>问题4：extern关键字的作用？<br>答：<br>1用于修饰变量或函数，表明该变量或函数都是在别的文件中定义的，提示编译器在其他文件中寻找定义。<br>extern int a;<br>extern int *p;<br>extern int array[];<br>extern void fun(void);<br>其中，在函数的声明带有关键字extern，仅仅是暗示这个函数可能在别的源文件中定义，没有其他作用。如：<br>头文件A：A_MODULE.h中包含<br>extern int func(int a, int b);<br>源文件A: A_MODULE.c中<br>#include “A_MODULE.h”<br>int func(int a, int b)<br>{<br>     returna+b;<br>}<br>此时，展开头文件A_MODULE.h后，为<br>extern int func(int a, int b);/</em>虽然暗示可能在别的源文件中定义，但又在本文件中定义，所以extern并没有起到什么作用，但也不会产生错误</em>/<br>int func(int a, int b)<br>{<br>     returna+b;<br>}<br>而源文件B：B_MODULE.c中，<br>#include “A_MODULE.h”<br>int ret = func(10,5);/<br>展开头文件A_MODULE.h后，为<br>extern int func(int a, int b);/<em>暗示在别的源文件中定义，所以在下面使用func(5,10)时，在链接的时候到别的目标文件中寻找定义</em>/<br>int ret = func(10,5);<br>2 用于extern “c<br>extern “c”的作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern “C”后，会指示编译器这部分代码按C语言的编译方式进行编译，而不是C++的。<br>C++作为一种与C兼容的语言，保留了一部分面向过程语言的特点，如可以定义不属于任何类的全局变量和函数，但C++毕竟是一种面向对象的语言，为了支持函数的重载，对函数的编译方式与C的不同。例如，在C++中，对函数void fun(int,int)编译后的名称可能是_fun_int_int，而C中没有重载机制，一般直接利用函数名来指定编译后函数的名称，如上面的函数编译后的名称可能是_fun。<br>这样问题就来了，如果在C++中调用的函数如上例中的fun(1,2)是用C语言在源文件a_module.c中实现和编译的，那么函数fun在目标文件a_module.obj中的函数名为_fun，而C++在源文件b_module.cpp通过调用其对外提供的头文件a_module.h引用后，调用fun，则直接以C++的编译方式来编译，使得fun编译后在目标文件b_module.obj的名称为_fun_int_int，这样在链接的时候，因为_fun_int_int的函数在目标文件a_module.obj中不存在，导致了链接错误。<br>解决方法是让b_module.cpp知道函数fun是用C语言实现和编译了，在调用的时候，采用与C语言一样的方式来编译。该方法可以通过extern “C”来实现（具体用法见下面）。一般，在用C语言实现函数的时候，要考虑到这个函数可能会被C++程序调用，所以在设计头文件时，应该这样声明头文件：<br>/<em>头文件a_module.h</em>/<br>/<em>头文件被CPP文件include时，CPP文件中都含有该自定义的宏__cplusplus</em>/<br>/<em>这样通过extern “C”告诉C++编译器，extern “C”{}里包含的函数都用C的方式来编译</em>/<br>#ifdef <strong>cplusplus<br>extern “C”<br>{<br>#endif<br>extern void fun(int a, int b);<br>#ifdef __cplusplus<br>}<br>#endif<br>extern “C”的使用方式<br>\1. 可以是单一语句<br>  extern “C” doublesqrt(double);<br>\2. 可以是复合语句, 相当于复合语句中的声明都加了extern “C”<br>  extern “C”<br>  {<br>    double sqrt(double);<br>    int min(int, int);<br>  }<br>3.可以包含头文件，相当于头文件中的声明都加了extern”C”<br>  extern “C”<br>  {<br>    #include <cmath><br> }<br>\4. 不可以将extern”C” 添加在函数内部<br>\5. 如果函数有多个声明，可以都加extern”C”, 也可以只出现在第一次声明中，后面的声明会接受第一个链接指示符的规则。<br>\6. 除extern”C”, 还有extern “FORTRAN” 等。<br>问题5：sizeof关键字的作用？<br>答：<br>sizeof是在编译阶段处理，且不能被编译为机器码。sizeof的结果等于对象或类型所占的内存字节数。sizeof的返回值类型为size_t。<br>变量：int a;  sizeof(a)为4；<br>指针：int <em>p;  sizeof(p)为4；<br>数组：int b[10]; sizeof(b)为数组的大小，4<em>10；int c[0]; sizeof(c)等于0<br>结构体：struct (int a; char ch;)s1; sizeof(s1)为8 与结构体字节对齐有关。<br>注意：不能对结构体中的位域成员使用sizeof<br>sizeof(void)等于1<br>sizeof(void *)等于4<br>3 结构体<br>问题1：结构体的赋值？<br>答：<br>C语言中对结构体变量的赋值或者在初始化或者在定义后按字段赋值。<br>方式1：初始化<br>struct tag<br>{<br>   chara;<br>  int b;<br>}x = {‘A’, 1};/</em>初始化</em>/<br>或<br>struct tag<br>{<br>char a;<br>int b;<br>};<br>struct tag x = {‘A’,1};/<em>在定义变量时初始化</em>/<br>GNU C中可使用另外一种方式：<br>struct tag<br>{<br>char a;<br>int b;<br>}x =<br>{<br>.a = ‘A’,<br>.b =1;<br>};<br>或<br>struct tag<br>{<br>char a;<br>int b;<br>};<br>struct tag x =<br>{<br>   .a= ‘A’,<br>  .b=1,<br>};<br>方式2：定义变量后按字段赋值<br>struct tag<br>{<br>char a;<br>int b;<br>};<br>struct tag x;/<em>定义变量</em>/<br>x.a = ‘A’;/<em>按字段赋值</em>/<br>x.b = 1; /<em>按字段赋值</em>/<br>而当你使用初始化的方式来赋值时，如x = {‘A’,1};则出错。<br>方式3：结构变量间的赋值<br>struct tag<br>{<br>   chara;<br>  int b;<br>};<br>struct tag x,y;<br>x.a=’A’;<br>x.b=1;<br>y = x;/<em>结构变量间直接赋值</em>/<br>问题2：结构体变量如何比较？<br>答：虽然结构体变量之间可以通过=直接赋值，但不同通过比较符如==来比较，因为比较符只作用于基本数据类型。这个时候，只能通过int memcmp(const void <em>s1, const void <em>s2, size_t n);来进行内存上的比较。<br>问题3：结构体位域<br>答：<br>位域是一个或多个位的字段，不同长度的字段（如声明为unsigned int类型）存储于一个或多个其所声明类型的变量中（如整型变量中）。<br>位域的类型：可以是char、short、int，多数使用int，使用时最好带上signed或unsigned<br>位域的特点：字段可以不命名，如unsignedint :1;可用来填充；unsigned int :0; 0宽度用来强制在下一个整型（因此处是unsigned int类型）边界上对齐。<br>位域的定义：<br>struct st1<br>{<br>unsigned chara:7;/</em>字段a占用了一个字节的7个bit</em>/<br>unsigned charb:2;/<em>字段b占用了2个bit</em>/<br>unsigned charc:7;/<em>字段c占用了7个bit</em>/<br>}s1;<br>sizeof(s1)等于3。因为一个位域字段必须存储在其位域类型的一个单元所占空间中,不能横跨两个该位域类型的单元。也就是说，当某个位域字段正处于两个该位域类型的单元中间时，只使用第二个单元，第一个单元剩余的bit位置补（pad）0。<br>于是可知Sizeof(s2)等于3<em>sizeof(int)即12<br>struct st2<br>{<br>unsigned inta:31;<br>unsigned intb:2;/*前一个整型变量只剩下1个bit，容不下2个bit，所以只能存放在下一个整型变量</em>/<br>unsigned int c:31;<br>}s2;<br>位域的好处：<br>    1.有些信息在存储时，并不需要占用一个完整的字节， 而只需占几个或一个二进制位。例如在存放一个开关量时，只有0和1 两种状态，用一位二进位即可。这样节省存储空间，而且处理简便。这样就可以把几个不同的对象用一个字节的二进制位域来表示。<br>    2.可以很方便的利用位域把一个变量给按位分解。比如只需要4个大小在0到3的随即数，就可以只rand()一次，然后每个位域取2个二进制位即可，省时省空间。<br>位域的缺点：<br>不同系统对位域的处理可能有不同的结果，如位段成员在内存中是从左向右分配的还是从右向左分配的，所以位域的使用不利于程序的可移植性。<br>问题4：结构体成员数组大小为0<br>结构体数组成员的大小为0是GNU C的一个特性。好处是可以在结构体中分配不定长的大小。如<br>typedef struct st<br>{<br>    inta;<br>int b;<br>char c[0];<br>}st_t;<br>sizeof(st_t)等于8，即char c[0]的大小为0.<br>#define SIZE 100<br>st_t *s = (st_t *)malloc(sizeof(st_t) + SIZE);<br>4 函数<br>问题1：函数参数入栈顺序<br>答：<br>C语言函数参数入栈顺序是从右向左的，这是由编译器决定的，更具体的说是函数调用约定决定了参数的入栈顺序。C语言采用是函数调用约定是</cmath></strong>cdecl的，所以对于函数的声明，完整的形式是：int __cdecl func(int a, int b);<br>问题2：inline内联函数<br>答：<br>inline关键字仅仅是建议编译器做内联展开处理，即是将函数直接嵌入调用程序的主体，省去了调用/返回指令。<br>5 内存分配回收<br>问题1： malloc/free与new/delete的区别<br>答：</p>
<p>1) malloc与free是C/C++语言的标准库函数，new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。<br>2) 对于非内部数据类型的对象而言，光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数，对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符，不在编译器控制权限之内，不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new，以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。<br>我们不要企图用malloc/free来完成动态对象的内存管理，应该用new/delete。由于内部数据类型的“对象”没有构造与析构的过程，对它们而言malloc/free和new/delete是等价的。<br>3) 既然new/delete的功能完全覆盖了malloc/free，为什么C++不把malloc/free淘汰出局呢？这是因为C++程序经常要调用C函数，而C程序只能用malloc/free管理动态内存。<br>如果用free释放“new创建的动态对象”，那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”，结果也会导致程序出错，但是该程序的可读性很差。所以new/delete必须配对使用，malloc/free也一样。<br>问题2：malloc(0)返回值<br>答：如果请求的长度为0，则标准C语言函数malloc返回一个null指针或不能用于访问对象的非null指针，该指针能被free安全使用。<br>6 可变参数列表<br>可变参数列表是通过宏来实现的，这些宏定义在stdarg.h头文件，它是标准库的一部分。这个头文件声明了一个类型va_list和三个宏：va_start、va_arg和va_end。<br>typedef char <em>va_list;<br>#define va_start(ap, A)  (void)((ap) = (char *)&amp;(A) + _Bnd(A, _AUPBND))<br>#define va_arg(ap, T)  (</em>(T )((ap) += _Bnd(T, _AUPBND)) - _Bnd(T, _ADNBND)))<br>#define va_end(ap) (void)0<br>int print(char <em>format, …)<br>宏va_start的第一个参数是va_list类型的变量，第二个参数是省略号前最后一个有名字的参数，功能是初始化va_list类型的变量，将其值设置为可变参数的第一个变量。<br>宏va_arg的第一个参数是va_list类型的变量，第二个参数是参数列表的下一个参数的类型。va_arg返回va_list变量的值，并使该变量指向下一个可变参数。<br>宏va_end是在va_arg访问完最后一个可变参数之后调用的。<br>问题1：实现printf函数<br>/*（转载）<br> \</em> A simple printf function. Only support the following format:<br> * Code Format<br> * %c character<br> * %d signed integers<br> * %i signed integers<br> * %s a string of characters<br> * %o octal<br> * %x unsigned hexadecimal<br> <em>/<br>int my_printf( const char</em> format, …)<br>{<br>  va_list arg;<br>  int done = 0;<br>  va_start (arg, format);<br>  while( <em>format != ‘\0’)<br>  {<br>    if( *format == ‘%’)<br>    {<br>      if( *(format+1) == ‘c’ )<br>      {<br>        char c = (char)va_arg(arg, int);<br>        putc(c, stdout);<br>      } else if( *(format+1) == ‘d’ || *(format+1) == ‘i’)<br>      {<br>        char store[20];<br>        int i = va_arg(arg, int);<br>        char</em> str = store;<br>        itoa(i, store, 10);<br>        while( <em>str != ‘\0’) putc(*str++, stdout);<br>      } else if( *(format+1) == ‘o’)<br>      {<br>        char store[20];<br>        int i = va_arg(arg, int);<br>        char</em> str = store;<br>        itoa(i, store, 8);<br>        while( <em>str != ‘\0’) putc(*str++, stdout);<br>      } else if( *(format+1) == ‘x’)<br>      {<br>        char store[20];<br>        int i = va_arg(arg, int);<br>        char</em> str = store;<br>        itoa(i, store, 16);<br>        while( <em>str != ‘\0’) putc(*str++, stdout);<br>      } else if( *(format+1) == ‘s’ )<br>      {<br>        char</em> str = va_arg(arg, char<em>);<br>        while( <em>str != ‘\0’) putc(</em>str++, stdout);<br>      }<br>      // Skip this two characters.<br>      format += 2;<br>    } else {<br>      putc(*format++, stdout);<br>    }<br>  }<br>  va_end (arg);<br>  return done;<br>}<br>7 其他<br>问题1：ASSERT()的作用<br>答:ASSERT()是一个调试程序时经常使用的宏，在程序运行时它计算括号内的表达式，如果表达式为FALSE (0), 程序将报告错误，并终止执行。如果表达式不为0，则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据，如果出现了终止程序以免导致严重后果，同时也便于查找错误。例如，变量n在程序中不应该为0，如果为0可能导致错误，你可以这样写程序：<br>……<br>ASSERT( n != 0);<br>k = 10/ n;<br>…..<br>ASSERT只有在Debug版本中才有效，如果编译为Release版本则被忽略。<br>assert()的功能类似，它是ANSI C标准中规定的函数，它与ASSERT的一个重要区别是可以用在Release版本中。<br>问题2：system(“pause”);的作用<br>答:系统的暂停程序，按任意键继续，屏幕会打印，”按任意键继续。。。。。”省去了使用getchar（）；<br>问题3：请问C++的类和C里面的struct有什么区别？<br>答:c++中的类具有成员保护功能，并且具有继承，多态这类oo特点，而c里的struct没有。c里面的struct没有成员函数,不能继承,派生等等.<br>8 找错题<br>试题1：<br>void test1()<br>{<br>　　char string[10];<br>　　char</em> str1 = “0123456789”;<br>　　strcpy(string, str1);<br>}<br>解答：字符串str1有11个字节（包括末尾的结束符’\0’），而string只有10个字节，故而strcpy会导致数组string越界。<br>试题2：<br>void test2()<br>{<br>　　char string[10], str1[10];<br>　　int i;<br>　　for(i=0; i&lt;10; i++)<br>　　{<br>　　  str1= ‘a’;<br>　　}<br>　　strcpy(string, str1);<br>}<br>解答：因为str1没有结束符’\0’，故而strcpy复制的字符数不确定。strcpy源码如下：<br>[cpp] view plain copy<br>#include &lt;string.h&gt;<br>char <em>strcpy(char <em>s1, cosnt char *s2)<br>{<br>  char *s = s1;<br>  for (s = s1; (</em>s++ = <em>s2++) != ‘\0’;)/</em>最后的结束符’\0’也会被复制</em>/<br>    ;<br>  return s1;<br>}<br>试题3：<br>void test3(char* str1)<br>{<br>　　char string[10];<br>　　if(strlen(str1) &lt;= 10 )<br>　　{<br>　　  strcpy(string, str1);<br>　　}<br>}<br>解答：应修改为if (strlen(str1) &lt; 10)，因为strlen的结果未统计最后的结束符’\0’。strlen的源码如下：<br>[cpp] view plain copy<br>#include &lt;string.h&gt;<br>size_t strlen(const char <em>s)<br>{<br>  const char <em>sc;<br>  for (sc = s; *sc != ‘\0’; ++sc)/</em>不包含最后的结束符’\0’</em>/<br>    ;<br>  return (sc - s);<br>}<br>试题4：<br>void GetMemory(char <em>p)<br>{<br>　　p = (char <em>)malloc( 100 );<br>}<br>void Test( void )<br>{<br>　 char *str = NULL;<br>　 GetMemory(str);<br>　 strcpy(str,”hello world”);<br>　 printf(str);<br>}<br>解答：C语言中的函数参数为传值参数，在函数内对形参的修改并不能改变对应实参的值。故而调用GetMemory后，str仍为NULL。<br>试题5：<br>char *GetMemory( void )<br>{<br>　　char p[] = “hello world”;<br>　　return p;<br>}<br>void Test( void )<br>{<br>　　char *str = NULL;<br>　　str = GetMemory();<br>　　printf(str);<br>}<br>解答：GetMemory中，p为局部变量，在函数返回后，该局部变量被回收。故而str仍为NULL<br>试题6：<br>void GetMemory( char *</em>p, int num )<br>{<br>　　<em>p = (char *)malloc(num);<br>}<br>void Test( void )<br>{<br>　　char *str = NULL;<br>　　GetMemory(&amp;str, 100);<br>　　strcpy(str, “hello”);<br>　　printf(str);<br>}<br>解答：试题6避免了试题4的问题，但在GetMemory内，未对</em>p为NULL情况的判断。当*p不为NULL时，在printf后，也未对malloc的空间进行free<br>试题7：<br>void Test( void )<br>{<br>　　char *str = (char *)malloc( 100 );<br>　　strcpy(str, “hello” );<br>　　free(str);<br>　　… //省略的其它语句<br>}<br>解答：未对str为NULL的情况的判断，在free(str)后，str未设置为NULL，可能变成一个野指针（后面对str的操作可能会导致踩内存）。<br>试题8：<br>swap(int</em> p1,int* p2)<br>{<br>　　int <em>p;<br>　　*p = *p1;<br>　　*p1 = *p2;<br>　　*p2 = *p;<br>}<br>解答：在swap函数中，p是个野指针，可能指向系统区，导致程序运行的崩溃。故而，程序应改为：<br>swap(int</em> p1,int* p2)<br>{<br>　　int p;<br>　　p = *p1;<br>　　*p1 = *p2;<br>　　*p2 = p;<br>}<br>9 编程题<br>题1：判断字符串str2是否在字符串str1里。<br>[cpp] view plain copy<br>#include &lt;stdio.h&gt; </p>
<p>#define OK   1<br>#define ERROR 0 </p>
<p>int str_str(const char <em>str1, const char <em>str2)  {<br>  const char *s1 = NULL;<br>  const char *s2 = NULL;<br>  if (str1 == NULL) {<br>    return (str2 == NULL) ? OK : ERROR;<br>  }<br>  if (str2 == NULL) {<br>    return OK;<br>  }<br>  for (; *str1 != ‘\0’; str1++)  {<br>    if (</em>str1 == *str2)  {<br>      for (s1 = str1, s2 = str2; ; )  {<br>        if (</em>++s2 == ‘\0’)  {<br>          return OK;<br>        }<br>        else if (*++s1 != *s2)  {<br>          break;<br>        }<br>      }<br>    }<br>  }<br>  return ERROR;<br>} </p>
      <!-- reward -->
      <div id="reword-out">
        <div id="reward-btn">
          Donate
        </div>
      </div>
    </div>
    <!-- copyright -->
    <div class="declare">
      <ul class="post-copyright">
        <li>
          <i class="ri-copyright-line"></i>
          <strong>Copyright： </strong>
          Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
        </li>
      </ul>
    </div>
    <footer class="article-footer">
<div class="share-btn">
      <span class="share-sns share-outer">
        <i class="ri-share-forward-line"></i>
        分享
      </span>
      <div class="share-wrap">
        <i class="arrow"></i>
        <div class="share-icons">
          <a class="weibo share-sns" href="javascript:;" data-type="weibo">
            <i class="ri-weibo-fill"></i>
          </a>
          <a class="weixin share-sns wxFab" href="javascript:;" data-type="weixin">
            <i class="ri-wechat-fill"></i>
          </a>
          <a class="qq share-sns" href="javascript:;" data-type="qq">
            <i class="ri-qq-fill"></i>
          </a>
          <a class="douban share-sns" href="javascript:;" data-type="douban">
            <i class="ri-douban-line"></i>
          </a>
          <!-- <a class="qzone share-sns" href="javascript:;" data-type="qzone">
            <i class="icon icon-qzone"></i>
          </a> -->
          <a class="facebook share-sns" href="javascript:;" data-type="facebook">
            <i class="ri-facebook-circle-fill"></i>
          </a>
          <a class="twitter share-sns" href="javascript:;" data-type="twitter">
            <i class="ri-twitter-fill"></i>
          </a>
          <a class="google share-sns" href="javascript:;" data-type="google">
            <i class="ri-google-fill"></i>
          </a>
        </div>
      </div>
</div>
<div class="wx-share-modal">
    <a class="modal-close" href="javascript:;"><i class="ri-close-circle-line"></i></a>
    <p>扫一扫，分享到微信</p>
    <div class="wx-qrcode">
      <img src="//api.qrserver.com/v1/create-qr-code/?size=150x150&data=http://www.kangxh.ga/2021/03/09/C%E8%AF%AD%E8%A8%80%E9%9D%A2%E8%AF%95%E9%A2%984/" alt="微信分享二维码">
    </div>
</div>
<div id="share-mask"></div>  
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/C%E8%AF%AD%E8%A8%80/" rel="tag">C语言</a></li></ul>
    </footer>
  </div>
  <nav class="article-nav">
      <a href="/2021/03/10/C%E8%AF%AD%E8%A8%80%E6%95%B0%E7%BB%84%E8%BE%93%E5%87%BA%E7%9A%84%E4%B8%89%E7%A7%8D%E6%96%B9%E6%B3%95/" class="article-nav-link">
        <strong class="article-nav-caption">上一篇</strong>
        <div class="article-nav-title">
            C语言数组输出的三种方法
        </div>
      </a>
      <a href="/2021/03/09/C%E8%AF%AD%E8%A8%80%E9%9D%A2%E8%AF%95%E9%A2%983/" class="article-nav-link">
        <strong class="article-nav-caption">下一篇</strong>
        <div class="article-nav-title">C语言面试题3</div>
      </a>
  </nav>
<!-- valine评论 -->
<div id="vcomments-box">
  <div id="vcomments"></div>
</div>
<script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/valine@1.4.14/dist/Valine.min.js"></script>
<script>
  new Valine({
    el: "#vcomments",
    app_id: "lC7lsHHM0HSqJA3yOqH70saX-gzGzoHsz",
    app_key: "mCkqEEjUbhRIHjXJ7mtxTgfA",
    path: window.location.pathname,
    avatar: "monsterid",
    placeholder: "ヾﾉ≧∀≦)o来啊，快活啊!",
    recordIP: true,
  });
  const infoEle = document.querySelector("#vcomments .info");
  if (infoEle && infoEle.childNodes && infoEle.childNodes.length > 0) {
    infoEle.childNodes.forEach(function (item) {
      item.parentNode.removeChild(item);
    });
  }
</script>
<style>
  #vcomments-box {
    padding: 5px 30px;
  }
  @media screen and (max-width: 800px) {
    #vcomments-box {
      padding: 5px 0px;
    }
  }
  #vcomments-box #vcomments {
    background-color: #fff;
  }
  .v .vlist .vcard .vh {
    padding-right: 20px;
  }
  .v .vlist .vcard {
    padding-left: 10px;
  }
</style>
</article>
</section>
      <footer class="footer">
  <div class="outer">
    <ul>
      <li>
        Copyrights &copy;
        2020-2021
        <i class="ri-heart-fill heart_icon"></i> Mystery
      </li>
    </ul>
    <ul>
      <li>
        Powered by <a href="https://hexo.io" target="_blank">Hexo</a>
        <span class="division">|</span>
        Theme - <a href="https://github.com/Shen-Yu/hexo-theme-ayer" target="_blank">Ayer</a>
      </li>
    </ul>
    <ul>
      <li>
        <span>
  <span><i class="ri-user-3-fill"></i>Visitors:<span id="busuanzi_value_site_uv"></span></s>
  <span class="division">|</span>
  <span><i class="ri-eye-fill"></i>Views:<span id="busuanzi_value_page_pv"></span></span>
</span>
      </li>
    </ul>
    <ul>
    </ul>
    <ul>
    </ul>
    <ul>
      <li>
        <!-- cnzz统计 -->
        <script type="text/javascript" src='https://s9.cnzz.com/z_stat.php?id=1278069914&amp;web_id=1278069914'></script>
      </li>
    </ul>
  </div>
</footer>
      <div class="float_btns">
        <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>
<div class="todark" id="todark">
  <i class="ri-moon-line"></i>
</div>
      </div>
    </main>
    <aside class="sidebar on">
      <button class="navbar-toggle"></button>
<nav class="navbar">
  <div class="logo">
    <a href="/"><img src="/images/ayer-side.svg" alt="Mysterious Blog"></a>
  </div>
  <ul class="nav nav-main">
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    <li class="nav-item">
      <a class="nav-item-link" href="/categories">分类</a>
    </li>
    <li class="nav-item">
      <a class="nav-item-link" href="/tags">标签</a>
    </li>
    <li class="nav-item">
      <a class="nav-item-link" href="/friends">友链</a>
    </li>
    <li class="nav-item">
      <a class="nav-item-link" href="/player">影音</a>
    </li>
    <li class="nav-item">
      <a class="nav-item-link" href="/about">关于我</a>
    </li>
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      <a class="nav-item-link nav-item-search"  title="Search">
        <i class="ri-search-line"></i>
      </a>
      <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
        <i class="ri-rss-line"></i>
      </a>
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
    </aside>
    <script>
      if (window.matchMedia("(max-width: 768px)").matches) {
        document.querySelector('.content').classList.remove('on');
        document.querySelector('.sidebar').classList.remove('on');
      }
    </script>
    <div id="mask"></div>
<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>请我喝杯咖啡吧~</p>
  <div class="reward-box">
    <div class="reward-item">
      <img class="reward-img" src="https://gitee.com/LYmystery/PicGo/raw/master/img/alipay.jpg">
      <span class="reward-type">支付宝</span>
    </div>
    <div class="reward-item">
      <img class="reward-img" src="https://gitee.com/LYmystery/PicGo/raw/master/img/wechat.jpg">
      <span class="reward-type">微信</span>
    </div>
  </div>
</div>
<script src="/js/jquery-2.0.3.min.js"></script>
<script src="/js/lazyload.min.js"></script>
<!-- Tocbot -->
<script src="/js/tocbot.min.js"></script>
<script>
  tocbot.init({
    tocSelector: '.tocbot',
    contentSelector: '.article-entry',
    headingSelector: 'h1, h2, h3, h4, h5, h6',
    hasInnerContainers: true,
    scrollSmooth: true,
    scrollContainer: 'main',
    positionFixedSelector: '.tocbot',
    positionFixedClass: 'is-position-fixed',
    fixedSidebarOffset: 'auto'
  });
</script>
<script src="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.css">
<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js"></script>
<script src="/dist/main.js"></script>
<!-- ImageViewer -->
<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>
    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">
        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>
        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">
            <div class="pswp__top-bar">
                <!--  Controls are self-explanatory. Order can be changed. -->
                <div class="pswp__counter"></div>
                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>
                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>
            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>
            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>
            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>
        </div>
    </div>
</div>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css">
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"></script>
<script>
    function viewer_init() {
        let pswpElement = document.querySelectorAll('.pswp')[0];
        let $imgArr = document.querySelectorAll(('.article-entry img:not(.reward-img)'))
        $imgArr.forEach(($em, i) => {
            $em.onclick = () => {
                // slider展开状态
                // todo: 这样不好，后面改成状态
                if (document.querySelector('.left-col.show')) return
                let items = []
                $imgArr.forEach(($em2, i2) => {
                    let img = $em2.getAttribute('data-idx', i2)
                    let src = $em2.getAttribute('data-target') || $em2.getAttribute('src')
                    let title = $em2.getAttribute('alt')
                    // 获得原图尺寸
                    const image = new Image()
                    image.src = src
                    items.push({
                        src: src,
                        w: image.width || $em2.width,
                        h: image.height || $em2.height,
                        title: title
                    })
                })
                var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
                    index: parseInt(i)
                });
                gallery.init()
            }
        })
    }
    viewer_init()
</script>
<!-- MathJax -->
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
      tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
  });
  MathJax.Hub.Queue(function() {
      var all = MathJax.Hub.getAllJax(), i;
      for(i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
      }
  });
</script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@2.7.6/unpacked/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script>
  var ayerConfig = {
    mathjax: true
  }
</script>
<!-- Katex -->
<!-- busuanzi  -->
<script src="/js/busuanzi-2.3.pure.min.js"></script>
<!-- ClickLove -->
<!-- ClickBoom1 -->
<!-- ClickBoom2 -->
<!-- CodeCopy -->
<link rel="stylesheet" href="/css/clipboard.css">
<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
  function wait(callback, seconds) {
    var timelag = null;
    timelag = window.setTimeout(callback, seconds);
  }
  !function (e, t, a) {
    var initCopyCode = function(){
      var copyHtml = '';
      copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
      copyHtml += '<i class="ri-file-copy-2-line"></i><span>COPY</span>';
      copyHtml += '</button>';
      $(".highlight .code pre").before(copyHtml);
      $(".article pre code").before(copyHtml);
      var clipboard = new ClipboardJS('.btn-copy', {
        target: function(trigger) {
          return trigger.nextElementSibling;
        }
      });
      clipboard.on('success', function(e) {
        let $btn = $(e.trigger);
        $btn.addClass('copied');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-checkbox-circle-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPIED';
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-checkbox-circle-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
      clipboard.on('error', function(e) {
        e.clearSelection();
        let $btn = $(e.trigger);
        $btn.addClass('copy-failed');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-time-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPY FAILED';
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-time-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
    }
    initCopyCode();
  }(window, document);
</script>
<!-- CanvasBackground -->
    <div id="music">
    <iframe frameborder="no" border="1" marginwidth="0" marginheight="0" width="200" height="52"
        src="//music.163.com/outchain/player?type=2&id=22707008&auto=0&height=32"></iframe>
</div>
<style>
    #music {
        position: fixed;
        right: 15px;
        bottom: 0;
        z-index: 998;
    }
</style>
  </div>
</body>
</html>